package Game

import (
	"GameGo/po"
	"GameGo/tool"
	"fmt"
	"golang.org/x/image/math/f64"
	"math/rand"
)

func UpdateGameLogic(g *Game) {
	g.StartTime++
	if g.PlayerHP <= 0 {
		g.State = po.StateGameOver
		return
	}
	playerW := float64(g.PlayerImg.Bounds().Dx()) / 2
	playerH := float64(g.PlayerImg.Bounds().Dy()) / 2
	bulletW := float64(g.BulletImg.Bounds().Dx()) / 2
	bulletH := float64(g.BulletImg.Bounds().Dy()) / 2
	enemyW := float64(g.EnemyImg.Bounds().Dx()) / 2
	enemyH := float64(g.EnemyImg.Bounds().Dy()) / 2

	g.Player.PlayerMove()

	g.Player.PlayerShot(&g.Bullets)

	// 敌人生成
	g.EnemyTimer++
	r := (rand.Intn(6) + 6) * 10
	if g.EnemyTimer >= r && g.EnemyNum[0] > 0 {
		enemy := po.NewOrdinaryEnemy(g.GameLevel)
		g.Enemies = append(g.Enemies, enemy)
		g.EnemyScore += enemy.EnemyMaxHP
		g.EnemyNum[0]--
		g.EnemyTimer = 0

	}

	if g.StartTime%600 == 0 && g.EnemyNum[1] > 0 {
		enemy := po.NewEliteEnemy(g.GameLevel)
		g.Enemies = append(g.Enemies, enemy)
		g.EnemyScore += enemy.EnemyMaxHP
		g.EnemyNum[1]--
	}
	if g.EnemyNum[1] == 0 && g.EnemyNum[0] == 0 && g.EnemyNum[2] > 0 {
		enemy := po.NewBoss(g.GameLevel)
		g.Enemies = append(g.Enemies, enemy)
		g.EnemyScore += enemy.EnemyMaxHP
		g.EnemyNum[2]--
	}

	if g.EnemyScore > 60 {
		g.GameLevel = 2
	}

	if g.EnemyScore > 420 {
		g.GameLevel = 3
	}
	fmt.Println(g.GameLevel)
	for i := range g.Enemies {
		g.Enemies[i].EnemyShot(&g.Bullets, g.PlayerX, g.PlayerY)

	}
	// 敌人移动
	for i := range g.Enemies {
		g.Enemies[i].EnemyMove()
	}

	// 子弹移动
	var newBullets []po.Bullet
	bulletPos := f64.Vec2{g.PlayerX, g.PlayerY - 10}
	for _, b := range g.Bullets {
		bulletPos = b.Position
		nearestEnemy := tool.GetNearestEnemy(g.Enemies, bulletPos)
		b.TargetPos = f64.Vec2{nearestEnemy[0], nearestEnemy[1]}
		b.BulletMove()
		if !tool.IsOut(b.Position[0], b.Position[1]) && b.Life > 0 {
			newBullets = append(newBullets, b)
		}
	}
	g.Bullets = newBullets

	newBullets = g.Bullets[:0]
	for _, bullet := range g.Bullets {
		hit := false
		if bullet.BulletType == po.PlayerBullet {
			for i := range g.Enemies {
				ex, ey, _, _ := g.Enemies[i].EnemyOption(po.EnemyPosition, 0)
				if tool.IsColliding(bullet.Position[0], bullet.Position[1], bulletW, bulletH, ex, ey, enemyW, enemyH) {
					g.Enemies[i].EnemyOption(po.HitEnemy, bullet.Damage)
					hit = true
					_ = g.SoundHit.Rewind()
					g.SoundHit.Play()
					break
				}
			}
		} else if tool.IsColliding(bullet.Position[0], bullet.Position[1], bulletW, bulletH, g.PlayerX+10, g.PlayerY+30, playerW/6, playerH/6) {
			g.PlayerHP -= bullet.Damage
			hit = true
			_ = g.SoundShou.Rewind()
			g.SoundShou.Play()

		}

		if !hit {
			newBullets = append(newBullets, bullet)
		}
	}
	g.Bullets = newBullets

	for i := range g.Enemies {
		ex, ey, _, _ := g.Enemies[i].EnemyOption(po.EnemyPosition, 0)
		if tool.IsColliding(g.PlayerX, g.PlayerY, playerW, playerH, ex, ey, enemyW, enemyH) {
			g.PlayerHP -= 5
			g.Enemies[i].EnemyOption(po.OneKill, 0)
			break
		}
	}

	newEnemies := g.Enemies[:0]
	for i, _ := range g.Enemies {
		ex, ey, _, _ := g.Enemies[i].EnemyOption(po.EnemyPosition, 0)
		_, _, isDead, _ := g.Enemies[i].EnemyOption(po.IsDead, 0)
		_, _, _, exp := g.Enemies[i].EnemyOption(po.Exp, 0)
		if !isDead && !tool.IsOut(ex, ey) {
			newEnemies = append(newEnemies, g.Enemies[i])
		} else if isDead {
			_, _, _, typ := g.Enemies[i].EnemyOption(po.EnemyType, 0)
			_ = g.SoundOut.Rewind()
			g.SoundOut.Play()
			g.Score += exp
			g.Player.PlayerLevelUp(exp / 2)
			if typ == 2 && g.EnemyNum[2] == 0 {
				g.State = po.StateGameEnd
				return
			}

		}
	}
	g.Enemies = newEnemies
	g.Player.PlayerLevelUp(0)
	return
}
